package com.pengliu.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.pengliu.service.HttpService;
import com.pengliu.service.SetConnection;
import com.pengliu.util.Maps;

/**
 * Http请求服务类,提供简单的基本请求信息封装
 */
@Service
public class HttpServiceImpl implements HttpService{
	
	private boolean isShowLog = false;
	
	private Map<String,String> cookies = Maps.newConcurrentHashMap();
	
	public String requestGet(String url) throws Exception {
		return requestHttp(url, Method.GET, null, null);
	}
	
	public String requestGet(String url,Map<String,String> data) throws Exception {
		return requestHttp(url, Method.GET, data, null);
	}
	public String requestGet(String url,Map<String,String> data,Map<String,String> heads) throws Exception {
		SetConnection setConnection = new SetConnection() {
			@Override
			public String before(Connection conn) {
				if (null != heads && heads.size() > 0) {
					if(isShowLog) System.out.println("header:");
					for (Map.Entry<String, String> head : heads.entrySet()) {
						conn.header(head.getKey(), head.getValue());
						if(isShowLog) System.out.println("\t"+head.getKey()+"="+head.getValue());
					}
				}
				if (null != cookies && cookies.size() > 0) {
					if(isShowLog) System.out.println("cookies:"+JSON.toJSONString(cookies));
		            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
		            	conn.cookie(cookie.getKey(), cookie.getValue());
		            }
		        }
				return null;
			}
			@Override
			public String after(Response response) {
				cookies.putAll(response.cookies());
				return null;
			}
		};
		return requestHttp(url, Method.GET, data, setConnection);
	}
	
	public String requestGet(String url,SetConnection setConnection) throws Exception {
		return requestHttp(url, Method.GET, null, setConnection);
	}
	
	public String requestPost(String url,Map<String,String> data) throws Exception {
		return requestHttp(url, Method.POST, null, null);
	}
	
	@Override
	public String requestPost(String url, Map<String, String> data, Map<String, String> heads) throws Exception {
		return requestPost(url, data, heads, null);
	}
	
	public String requestPost(String url,Map<String,String> data,Map<String,String> heads,String body) throws Exception {
		SetConnection setConnection = new SetConnection() {
			@Override
			public String before(Connection conn) {
				if (null != heads && heads.size() > 0) {
					if(isShowLog) System.out.println("header:");
					for (Map.Entry<String, String> head : heads.entrySet()) {
						conn.header(head.getKey(), head.getValue());
						if(isShowLog) System.out.println("\t"+head.getKey()+"="+head.getValue());
					}
				}
				if (null != cookies && cookies.size() > 0) {
					if(isShowLog) System.out.println("cookies:"+JSON.toJSONString(cookies));
		            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
		            	conn.cookie(cookie.getKey(), cookie.getValue());
		            }
		        }
				if(null != body && body.length()>0) {
					conn.requestBody(body);
				}
				return null;
			}
			@Override
			public String after(Response response) {
				cookies.putAll(response.cookies());
				return null;
			}
		};
		return requestPost(url, data, setConnection);
	}
	
	public String requestPost(String url,Map<String,String> data,SetConnection setConnection) throws Exception {
		return requestHttp(url, Method.POST, data, setConnection);
	}
	
	public String requestHttp(String url,Method method,Map<String,String> data,SetConnection setConnection) throws Exception {
		return doRequestHttp(url, method, data, setConnection!=null?setConnection:new SetConnection() {
			@Override
			public String before(Connection conn) {
				if(isShowLog) System.out.println("cookies:"+JSON.toJSONString(cookies));
		        if (null != cookies && cookies.size() > 0) {
		            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
		            	conn.cookie(cookie.getKey(), cookie.getValue());
		            }
		        }
				return null;
			}

			@Override
			public String after(Response res) {
				cookies.putAll(res.cookies());
				return null;
			}
		});
	}
	
	public String doRequestHttp(String url,Method method,Map<String,String> data,SetConnection setConnection) throws Exception {
		if(isShowLog) System.out.println("********************************************************************");
		if(isShowLog) System.out.println("访问URL=\t\t"+url);
		if(isShowLog) System.out.println("参数:"+JSON.toJSONString(data));
		
		
		Connection conn = Jsoup.connect(url);
		
		setConnection.before(conn);
		
		if(null != data) {
			conn.data(data);
		}
		
		conn.method(method);
		
		conn.ignoreContentType(true);
		
		conn.timeout(0);
		
		Response response = conn.execute();
		
		setConnection.after(response);
		
		String result = response.body();
		
		if(isShowLog) System.out.println("********************************************************************");
		return result;
	}
	
	public byte[] downloadFile(String url) throws Exception {
		return downloadFile(url,null,null);
	}
	
	public byte[] downloadFile(String url,Map<String,String> data,SetConnection setConnection) throws Exception {
		return doDownloadFile(url, data, setConnection!=null?setConnection:new SetConnection() {
			@Override
			public String before(Connection conn) {
				return null;
			}

			@Override
			public String after(Response res) {
				for (Map.Entry<String, String> cookie : res.cookies().entrySet()) {
				}
				return null;
			}
		});
	}
	
	public byte[] doDownloadFile(String url,Map<String,String> data,SetConnection setConnection) throws IOException {
		Connection conn = Jsoup.connect(url);
		setConnection.before(conn);
		if(null != data) {
			conn.data(data);
		}
		conn.method(Method.GET);
		conn.ignoreContentType(true);
		Response response = conn.execute();
		setConnection.after(response);
		return response.bodyAsBytes();
	}
	
	public String uploadFile(String url,Map<String,String> data,File file,String fileRequestParam) throws Exception {
		Connection conn = Jsoup.connect(url);
		conn.method(Connection.Method.POST);
		conn.timeout(12000);
		conn.header("Content-Type", "multipart/form-data; boundary="+fileRequestParam);
		conn.ignoreHttpErrors(true);
		conn.ignoreContentType(true);
		if(null != data) {
			conn.data(data);
		}
		
		FileInputStream fis = new FileInputStream(file);
		conn.data(fileRequestParam, file.getName(), fis);
	    
		Response response = conn.execute();
		return response.body();
	}

	public Map<String, String> getCookies() {
		return cookies;
	}

	public void setCookies(Map<String, String> cookies) {
		this.cookies = cookies;
	}

	public boolean isShowLog() {
		return isShowLog;
	}

	public void setShowLog(boolean isShowLog) {
		this.isShowLog = isShowLog;
	}
	
	
}
